<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>前端文件下载方式汇总</title>

</head>
<body>
<!--a标签原生方式下载-->
<a href="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2023%2F0125%2F49be0a0bj00rp1sop002qc000hs00psm.jpg&thumbnail=660x2147483647&quality=80&type=jpg"
   download="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2023%2F0125%2F49be0a0bj00rp1sop002qc000hs00psm.jpg&thumbnail=660x2147483647&quality=80&type=jpg"
   target="view_window">下载图片</a>
<br/>
<button type="button" style="font-size: 18px" id="download1">a 标签实现下载方式1：url 地址下载</button>
<br/>
<button type="button" style="font-size: 18px" id="download2">a 标签实现下载方式2：文件流转blob对象下载</button>
<br/>
<button type="button" style="font-size: 18px" id="download3">window.open()实现下载</button>
<br/>
<button type="button" style="font-size: 18px" id="download4">构造表单方式下载</button>
<br/>
<button type="button" style="font-size: 18px" id="download5">location.href方式下载</button>
<br/>

<br/>

</body>

<script type="text/javascript">
    /**
     * <a> 标签实现下载方式1：url 地址下载
     * 1、设置a标签的href为需要下载的资源路径 调用click点击事件就会实现下载。
     * 2、如果下载的资源类型是浏览器可以解析的，比如.txt、.mp4等，浏览器不会下载而是会直接打开资源预览
     * 3、此时可以为a标签添加download属性设置下载的文件名和后缀，此时任何类型资源就都可实现下载，但如果资源不是同源，仍然会直接打开预览。
     * @param url ：文件 url 地址，绝对路径或者相对路径。如 http://www.baidu.com/images/1.jpg、/fileServer/uploadFiles/1.jpg
     * @param fileName ：文件名，如 1.jpg
     */
    function downloadFileByA(url, fileName) {
        // 获取heads中的filename文件名
        let a = document.createElement("a");
        a.style.display = "none";
        // 给a标签创建下载的链接
        a.href = url;
        // 下载后文件名
        a.download = fileName;
        // 把a标签作为子节点插入当前body下
        document.body.appendChild(a);
        // 点击a标签下载
        a.click();
        // 下载完成移除元素
        document.body.removeChild(a);
    }

    /**
     * 构造表单方式下载方式1-get请求
     * 1、通过动态创建表单元素，设置action为资源下载路径。
     * 2、设置表单隐藏并调用表单的submit方式
     * 3、同样针对浏览器无法解析的类型会下载，浏览器可解析的资源类型会直接打开预览。
     */
    function downloadFileByFormGet(url) {
        let form = document.createElement("form");
        form.method = "get";
        form.action = url;
        form.target = "_blank";
        form.style.display = 'none';
        document.body.appendChild(form);
        form.submit();
        document.body.removeChild(form);
    }

    /**
     * window.open('下载的地址')实现下载
     * 1、利用打开新tab方式实现下载
     * 2、如果资源是浏览器无法解析的类型 会关闭tab 触发下载，但如果资源是浏览器可以解析的类型，还是会直接打开预览。
     */
    function downloadFileByWindow(url) {
        window.open(url);
    }

    /**
     * <a> 标签实现下载方式2：文件流转blob对象下载
     * @param streamData ：后台返回的文件流
     * @param type ：内容类型，如 octet-stream
     * @param fileName ：文件名，如 1.jpg
     */
    function downloadFileByStream(streamData, type, fileName) {
        let blob = new Blob([streamData], {type: `application/${type};charset=utf-8`});
        let downloadElement = document.createElement('a');
        // 创建下载的链接
        let href = window.URL.createObjectURL(blob);
        downloadElement.href = href;
        // 下载后文件名
        downloadElement.download = fileName;
        document.body.appendChild(downloadElement);
        // 点击下载
        downloadElement.click();
        // 下载完成移除元素
        document.body.removeChild(downloadElement);
        // 释放掉blob对象
        window.URL.revokeObjectURL(href);
    }

    window.onload = function () {
        document.getElementById("download1").addEventListener("click", function () {
            // 文本下载，因为跨域了，所以浏览器能解析时，仍然会直接打开预览。
            let src = "https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2023%2F0125%2F49be0a0bj00rp1sop002qc000hs00psm.jpg&thumbnail=660x2147483647&quality=80&type=jpg";
            let fileName = "2F49be0a0bj00rp1sop002qc000hs00psm.jpg";
            downloadFileByA(src, fileName);
        });

        document.getElementById("download2").addEventListener("click", function () {
            // ajax 异步请求，后台返回流进行下载。
            var request = new XMLHttpRequest();
            request.open("GET", "/fileServer/generateScript", true);
            request.responseType = "application/octet-stream";
            request.onload = function (e) {
                downloadFileByStream(e.target.response, "octet-stream", "a.sql");
            };
            request.send();
        });

        document.getElementById("download3").addEventListener("click", function () {
            let src = "https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2023%2F0125%2F49be0a0bj00rp1sop002qc000hs00psm.jpg&thumbnail=660x2147483647&quality=80&type=jpg";
            downloadFileByWindow(src);
        });

        document.getElementById("download4").addEventListener("click", function () {
            let src = "https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2023%2F0125%2F49be0a0bj00rp1sop002qc000hs00psm.jpg&thumbnail=660x2147483647&quality=80&type=jpg";
            // let src = 'http://localhost:8080/fileServer/uploadFiles/%E5%8F%96%E6%B6%88%E5%85%B3%E6%9C%BA.bat';
            // let src = '/fileServer/uploadFiles/a7624c0569db49e2ad496b903688f960_copy.png';
            downloadFileByFormGet(src);
        });

        document.getElementById("download5").addEventListener("click", function () {
        });
    };
</script>

</html>